const fs = require('fs');
const gulp = require('gulp');
const { Transform } = require('stream');

// Gulp 入口文件
// >=4.0 所有任务都是异步任务 需要手动通过done函数标记完成
exports.task_001 = (done) => {
  console.log('this is task_001');

  done(); // 标记完成
};

// 默认任务
exports.default = (done) => {
  console.log('this is default task');

  done();
};

// <4.0
// 使用task函数注册任务 (不推荐)
gulp.task('task_old', (done) => {
  console.log('this is <4.0 task');
  done();
});

const task_002 = (done) => {
  setTimeout(() => {
    console.log('this is task_002');
    done();
  }, 1000);
};
const task_003 = (done) => {
  setTimeout(() => {
    console.log('this is task_003');
    done();
  }, 1000);
};
const task_004 = (done) => {
  setTimeout(() => {
    console.log('this is task_004');
    done();
  }, 1000);
};

// 串行任务
exports.series = gulp.series(task_002, task_003, task_004);
// 并行任务
exports.parallel = gulp.parallel(task_002, task_003, task_004);

// 异步任务
// 方法一：callback 回调函数
exports.task_005 = (done) => {
  console.log('this is task_005');
  done();
  // 标记错误
  // done(new Error('task_005 error'))
};

// 方法二：返回一个 Promise 对象
exports.task_006 = () => {
  console.log('this is task_006');

  return Promise.resolve();
  // return Promise.reject(new Error('task_005 error'))
};

const timeoutFn = (time) => {
  return new Promise((resolve) => {
    setTimeout(resolve, time);
  });
};
// node >= 8.0
exports.task_007 = async () => {
  await timeoutFn(1000);
  console.log('this is task_007');
};

// 方法三：通过 stream 方法
exports.task_008 = (done) => {
  const readStream = fs.createReadStream('package.json');
  const wirteStream = fs.createWriteStream('package_001.json');
  readStream.pipe(wirteStream);
  return readStream;
  // 等同
  // readStream.on('end', () => {
  //   done()
  // })
};

exports.task_009 = () => {
  // 文件读取流
  const read = fs.createReadStream('package.json');
  // 文件写入流
  const write = fs.createWriteStream('package_002.json');
  // 文件转换流
  const transform = new Transform({
    transform: (chunk, encoding, callback) => {
      // 核心转换过程
      const input = chunk.toString();
      const output = input.replace(/\s/g, '');
      callback(null, output);
    },
  });

  read.pipe(transform).pipe(write);

  return read;
};

const { src, dest, parallel, series } = require('gulp');
const loadPlugins = require('gulp-load-plugins');
const plugins = loadPlugins();
const del = require('del');

const scss = () => {
  return src('src/Engineering/scss/*.scss')
    .pipe(plugins.sass())
    .pipe(plugins.cleanCss())
    .pipe(
      plugins.rename({
        // extname: '.min.css',
        extname: '.css',
      })
    )
    .pipe(dest('tempGulp/css'));
};
const script = () => {
  return src('src/Engineering/es6/*.js')
    .pipe(
      plugins.babel({
        presets: ['@babel/preset-env'],
      })
    )
    .pipe(dest('tempGulp/js'));
};
const html = () => {
  return src('src/Engineering/*.html').pipe(dest('tempGulp'));
  // .pipe(useRef())
};

const clean = () => {
  return del(['distGulp', 'tempGulp']);
};

const { watch } = require('gulp');
const browserSync = require('browser-sync');
const bs = browserSync.create();

const image = () => {
  return src('static/EG_*.png', { base: '.' })
    .pipe(plugins.imagemin())
    .pipe(dest('distGulp'))
    .pipe(bs.reload({ stream: true }));
};

const server = () => {
  watch('src/Engineering/scss/*.scss', scss);
  watch('src/Engineering/es6/*.js', script);
  watch('src/Engineering/*.html', html);
  // watch('static/EG_*.png', bs.reload())

  bs.init({
    notify: false,
    port: 8080,
    files: 'tempGulp/**',
    server: {
      baseDir: ['tempGulp', 'src'],
      // 指定对应引用所指向的目录
      // routes: {
      //   '/node_modules': 'node_modules'
      // }
    },
  });
};

const useref = () => {
  return src('tempGulp/*.html', { base: 'tempGulp' })
    .pipe(
      plugins.useref({
        // 资源寻找文件目录
        searchPath: ['tempGulp', '.'],
      })
    )
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(
      plugins.if(
        /\.html$/,
        plugins.htmlmin({
          collapseWhitespace: true,
          minifyCSS: true,
          minifyJS: true,
        })
      )
    )
    .pipe(dest('distGulp'));
};

const compile = parallel(scss, script, html);

const build = series(clean, parallel(image, compile), useref);

const dev = series(compile, server);

module.exports = {
  clean,
  build,
  dev,
};
